﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KylinORM.Utils;

namespace KylinORM.Aspect
{
    /// <summary>
    /// 实体字段默认的查询方式
    /// </summary>
    public class ESelectMethod : ICloneable<ESelectMethod>
    {
        private string template = "";
        private ESelectMethod(string template)
        {
            this.template = template;
        }
        /// <summary>
        /// 返回表示当前 System.Object 的 System.String
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.template;
        }
        /// <summary>
        /// 返回该字符串的哈希代码
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.ToString().GetHashCode();
        }
        /// <summary>
        /// 确定指定的 System.Object 是否等于当前的 System.Object
        /// </summary>
        /// <param name="obj">与当前的 System.Object 进行比较的 System.Object</param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return this.GetHashCode() == obj.GetHashCode();
        }

        /// <summary>
        /// 等于
        /// </summary>
        public static ESelectMethod Equal = new ESelectMethod("{0}={1}");
        /// <summary>
        /// 不等于
        /// </summary>
        public static ESelectMethod NotEqual = new ESelectMethod("{0}<>{1}");
        /// <summary>
        /// 相似与
        /// </summary>
        public static ESelectMethod Like = new ESelectMethod("{0} like '%'+{1}+'%'");
        /// <summary>
        /// 大于
        /// </summary>
        public static ESelectMethod GreaterThan = new ESelectMethod("{0}>{1}");
        /// <summary>
        /// 大于等于
        /// </summary>
        public static ESelectMethod GreaterThanOrEqual = new ESelectMethod("{0}>={1}");
        /// <summary>
        /// 小于
        /// </summary>
        public static ESelectMethod LessThan = new ESelectMethod("{0}<{1}");
        /// <summary>
        /// 小于等于
        /// </summary>
        public static ESelectMethod LessThanOrEqual = new ESelectMethod("{0}<={1}");



        /// <summary>
        /// 使用自定义查询条件
        /// </summary>
        /// <param name="template">查询模板，{0}代表字段名称 {1}代表字段值</param>
        /// <returns></returns>
        /// <example>以下语句将被翻译为[FieldName] like '%'+@FieldValue+'%'
        /// <code>{0} like '%'+{1}+'%'</code>
        /// </example>
        public static ESelectMethod CustomMethod(string template)
        {
            return new ESelectMethod(template);
        }

        ESelectMethod ICloneable<ESelectMethod>.Clone()
        {
            return new ESelectMethod(this.template);
        }

        object ICloneable.Clone()
        {
            return ((ICloneable<ESelectMethod>)this).Clone();
        }



        /// <summary>
        /// 默认查询方式到自定义查询方式的映射
        /// </summary>
        private static Dictionary<ESelectMethodBase, ESelectMethod> selectMethodMap = new Dictionary<ESelectMethodBase, ESelectMethod>
        {
            { ESelectMethodBase.Equal, ESelectMethod.Equal },
            { ESelectMethodBase.NotEqual, ESelectMethod.NotEqual },
            { ESelectMethodBase.Like, ESelectMethod.Like },
            { ESelectMethodBase.GreaterThan, ESelectMethod.GreaterThan },
            { ESelectMethodBase.GreaterThanOrEqual, ESelectMethod.GreaterThanOrEqual },
            { ESelectMethodBase.LessThan, ESelectMethod.LessThan },
            { ESelectMethodBase.LessThanOrEqual, ESelectMethod.LessThanOrEqual },
            { ESelectMethodBase.CustomMethod, ESelectMethod.CustomMethod("") }
        };
        
        /// <summary>
        /// 将默认查询方式转换为自定义查询方式
        /// </summary>
        /// <param name="selectMethod"></param>
        /// <returns></returns>
        public static implicit operator ESelectMethod(ESelectMethodBase selectMethod)
        {
            return selectMethodMap[selectMethod];
        }
    }
}
